package pers.dawnyang.modular.system.controller;

import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import pers.dawnyang.common.annotation.OperLog;
import pers.dawnyang.common.domain.Result;
import pers.dawnyang.common.domain.entity.SysRole;
import pers.dawnyang.common.domain.entity.SysUser;
import pers.dawnyang.common.enums.OperType;
import pers.dawnyang.common.enums.ResultEnum;
import pers.dawnyang.common.util.ResultUtil;
import pers.dawnyang.common.util.excel.EasyExcelUtil;
import pers.dawnyang.config.shiro.ShiroUtil;
import pers.dawnyang.modular.system.domain.request.user.UserDeptReqU;
import pers.dawnyang.modular.system.domain.request.user.UserReqC;
import pers.dawnyang.modular.system.domain.request.user.UserReqR;
import pers.dawnyang.modular.system.domain.request.user.UserReqU;
import pers.dawnyang.modular.system.domain.request.user.UserRoleReqU;
import pers.dawnyang.modular.system.domain.response.user.UserDeptRes;
import pers.dawnyang.modular.system.domain.response.user.UserExcelRes;
import pers.dawnyang.modular.system.domain.response.user.UserRes;
import pers.dawnyang.modular.system.domain.response.user.UserRoleRes;
import pers.dawnyang.modular.system.service.UserService;

/**
 * 用户管理
 * 
 * @author dawn yang
 * 
 */

@RequestMapping("/sys/user")
@Controller
@Validated
public class UserController {

  @Autowired
  private UserService userService;

  @RequiresPermissions("sys:user:index")
  @GetMapping("/index")
  public String index() {
    return "/sys/user/index";
  }

  @RequiresPermissions("sys:user:add")
  @GetMapping("/addView")
  public String addView() {
    return "/sys/user/addView";
  }

  @RequiresPermissions("sys:user:edit")
  @GetMapping("/editView")
  public String editView(@RequestParam("id") Long id, ModelMap model) {
    SysUser sysUser = userService.getById(id);
    UserRes userRes = new UserRes();
    BeanUtils.copyProperties(sysUser, userRes);
    model.put("model", JSON.toJSONString(userRes));
    return "/sys/user/editView";
  }

  @RequiresPermissions("sys:user:list")
  @PostMapping("/getPage")
  @ResponseBody
  public Result<Page<UserRes>> getPage(Page<UserRes> page, UserReqR req) {
    Page<UserRes> iPage = userService.getPage(page, req);
    return ResultUtil.success(iPage);
  }

  @RequiresPermissions("sys:user:detail")
  @GetMapping("/userDetail")
  public String getUserDetail(@RequestParam("id") Long id, ModelMap model) {
    UserRes userRes = userService.getUserDetail(id);
    model.put("model", JSON.toJSONString(userRes));
    return "/sys/user/userDetail";
  }

  /**
   * 获取用户关联角色
   * 
   * @param id
   * @return
   */
  @RequiresPermissions("sys:user:list")
  @GetMapping("/getUserRole")
  @ResponseBody
  public Result<List<UserRoleRes>> getUserRole(@RequestParam("id") Long id) {
    LambdaQueryWrapper<SysRole> lqw = new LambdaQueryWrapper<>();
    lqw.eq(SysRole::getRoleStatus, 1);
    List<UserRoleRes> list = userService.getUserRole(id);
    return ResultUtil.success(list);
  }

  /**
   * 获取用户关联机构部门
   * 
   * @param id
   * @return
   */
  @RequiresPermissions("sys:user:list")
  @GetMapping("/getUserDept")
  @ResponseBody
  public Result<List<UserDeptRes>> getUserDept(@RequestParam("id") Long id) {
    List<UserDeptRes> userDeptResList = userService.getUserDept(id);
    return ResultUtil.success(userDeptResList);
  }

  /**
   * 获取用户个人信息
   * 
   * @param id
   * @return
   */
  @RequiresPermissions("sys:user:edit")
  @GetMapping("/getUserInfo")
  @ResponseBody
  public Result<UserRes> getUserInfo(@RequestParam("id") Long id) {
    SysUser sysUser = userService.getById(id);
    UserRes userRes = new UserRes();
    BeanCopier b = BeanCopier.create(SysUser.class, UserRes.class, false);
    b.copy(sysUser, userRes, null);
    // BeanUtils.copyProperties(sysUser,
    // userRes);
    return ResultUtil.success(userRes);
  }

  @OperLog(operModul = "用户管理", operType = OperType.UPDATE)
  @RequiresPermissions("sys:user:edit")
  @PostMapping("/edit")
  @ResponseBody
  public Result<String> edit(@Validated UserReqU req) {
    boolean flag = userService.checkRoleLevel(req.getUserId());
    if (!flag) {
      return ResultUtil.error(ResultEnum.ERROR_EXCEEDROLE_USER);
    }
    SysUser sysUser = new SysUser();
    BeanUtils.copyProperties(req, sysUser);
    userService.updateById(sysUser);
    return ResultUtil.success();
  }

  @OperLog(operModul = "用户管理", operType = OperType.INSERT)
  @RequiresPermissions("sys:user:add")
  @PostMapping("/add")
  @ResponseBody
  public Result<String> add(@Validated UserReqC req) {
    SysUser sysUser = new SysUser();
    BeanUtils.copyProperties(req, sysUser);
    userService.save(sysUser);
    return ResultUtil.success();
  }

  /**
   * 删除用户
   * 
   * @param id
   * @return
   */
  @OperLog(operModul = "用户管理", operType = OperType.DELETE)
  @RequiresPermissions("sys:user:del")
  @PostMapping("/del")
  @ResponseBody
  public Result<String> del(@RequestParam("id") Long id) {
    boolean flag = userService.checkRoleLevel(id);
    if (!flag) {
      return ResultUtil.error(ResultEnum.ERROR_EXCEEDROLE_USER);
    }
    SysUser sysUser = new SysUser();
    sysUser.setUserId(id);
    sysUser.setUserStatus(0);
    userService.updateById(sysUser);
    return ResultUtil.success();
  }

  /**
   * 保存用户角色
   * 
   * @param req
   * @return
   */
  @OperLog(operModul = "用户管理", operType = OperType.GRANT)
  @RequiresPermissions({"sys:user:list", "sys:user:saveUserRole"})
  @PostMapping("/saveUserRole")
  @ResponseBody
  public Result<String> saveUserRole(UserRoleReqU req) {
    boolean flag = userService.checkRoleLevel(req.getUserId());
    if (!flag) {
      return ResultUtil.error(ResultEnum.ERROR_EXCEEDROLE_USER);
    }
    // 修改者不能授予等于或高于自己的角色权限
    Long minRoleLevel = ShiroUtil.getUserMinRoleLevel();
    Long roleLevel1 = userService.getMinRoleLevelByRoleIds(req.getRoleIds());
    if (roleLevel1 < minRoleLevel) {
      return ResultUtil.error(ResultEnum.ERROR_EXCEEDROLE_ROLE);
    }
    userService.saveUserRole(req);
    return ResultUtil.success();
  }


  /**
   * 保存用户部门
   * 
   * @param req
   * @return
   */
  @OperLog(operModul = "用户管理", operType = OperType.GRANT)
  @RequiresPermissions({"sys:user:list", "sys:user:saveUserDept"})
  @PostMapping("/saveUserDept")
  @ResponseBody
  public Result<String> saveUserDept(UserDeptReqU req) {
    boolean flag = userService.checkRoleLevel(req.getUserId());
    if (!flag) {
      return ResultUtil.error(ResultEnum.ERROR_EXCEEDROLE);
    }
    userService.saveUserDept(req);
    return ResultUtil.success();
  }

  /**
   * 重置用户密码
   * 
   * @param userId
   * @return
   */
  @OperLog(operModul = "用户管理", operType = OperType.UPDATE)
  @RequiresPermissions("sys:user:resetPwd")
  @PostMapping("/resetPwd")
  @ResponseBody
  public Result<String> resetPwd(@RequestParam("userId") Long userId) {
    boolean flag = userService.checkRoleLevel(userId);
    if (!flag) {
      return ResultUtil.error(ResultEnum.ERROR_EXCEEDROLE);
    }
    userService.resetPwd(userId);
    return ResultUtil.success();
  }


  /**
   * excel导出
   * 
   * @param req
   * @param response
   */
  @OperLog(operModul = "用户管理", operType = OperType.EXPORT)
  @RequiresPermissions("sys:user:export")
  @PostMapping("/export")
  @ResponseBody
  public void export(UserReqR req, HttpServletResponse response) {
    List<UserExcelRes> records = userService.export(req);
    EasyExcelUtil.writeToResponse(response, "用户信息", "用户列表", records, UserExcelRes.class);
  }


  /**
   * excel导入
   * 
   * @param file
   * @return
   * @throws IOException
   */
  @OperLog(operModul = "用户管理", operType = OperType.IMPORT)
  @RequiresPermissions("sys:user:import")
  @PostMapping("uploadExcel")
  @ResponseBody
  public Result<String> uploadExcel(@RequestParam(value = "excelFile") MultipartFile file)
      throws IOException {
    String res = userService.uploadExcel(file);
    return ResultUtil.success(200, res);

  }

}
